package com.dh.leetcode.k1;

import org.junit.Test;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * @ClassName: _1114_print_in_order
 * @Description: 1114. 按序打印
 * <p>
 * https://leetcode-cn.com/problems/print-in-order/
 * @Author: shouzimu
 * @Date: 2020/11/26 16:21
 */
public class _1114_print_in_order {

    class Foo {

        final CountDownLatch first;
        final CountDownLatch second;

        public Foo() {
            first = new CountDownLatch(1);
            second = new CountDownLatch(1);
        }

        public void first(Runnable printFirst) throws InterruptedException {
            // printFirst.run() outputs "first". Do not change or remove this line.
            printFirst.run();
            first.countDown();

        }

        public void second(Runnable printSecond) throws InterruptedException {
            first.await();
            // printSecond.run() outputs "second". Do not change or remove this line.
            printSecond.run();
            second.countDown();
        }

        public void third(Runnable printThird) throws InterruptedException {
            second.await();
            // printThird.run() outputs "third". Do not change or remove this line.
            printThird.run();
        }

        public void first() throws InterruptedException {
            System.out.println("first");
            first.countDown();
        }

        public void second() throws InterruptedException {
            first.await();
            System.out.println("second");
            second.countDown();
        }

        public void third() throws InterruptedException {
            second.await();
            System.out.println("third");
        }


    }

    @Test
    public void testFoo() {
        Foo foo = new Foo();
        new Thread(() -> {
            try {
                foo.second();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();


        new Thread(() -> {
            try {
                foo.first();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            try {
                foo.third();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();


        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
